﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace Sofire.Data.XSql
{
    /// <summary>
    /// 表示一个 XSql 绑定项。
    /// </summary>
    internal class XSqlBindItem
    {
        private string _Name;
        /// <summary>
        /// 获取绑定的名称。
        /// </summary>
        public string Name
        {
            get { return this._Name; }
            internal set { this._Name = value; }
        }

        private readonly string _Type;
        /// <summary>
        /// 获取绑定项的类型。
        /// </summary>
        public string Type
        {
            get { return this._Type; }
        }

        private int _Size;
        public int Size
        {
            get
            {
                return this._Size;
            }
        }

        /// <summary>
        /// 获取一个值，指示当前绑定项是否绑定。如果为 true，则以参数形式填充，否则以文本方式填充。
        /// </summary>
        public bool IsBind
        {
            get
            {
                return this._Type != XSqlBindType.None;
            }
        }

        internal XSqlBindItem(string expression)
        {
            if(expression == null) throw new ArgumentNullException("expression");
            if(expression.StartsWith("#{") && expression.EndsWith("}"))
            {
                var lines = expression.Split(',');
                this._Name = lines[0].Trim();
                if(lines.Length == 1)
                {
                    this._Name = this._Name.Substring(2, this._Name.Length - 3);
                }
                else
                {
                    this._Name = this._Name.Substring(2);
                    this._Type = lines[1].Trim().RemoveEnd();
                    if(lines.Length > 2)
                    {
                        this._Size = int.Parse(lines[2].Trim());
                    }
                }
            }
            else
            {
                this._Name = expression;
            }
        }

        /// <summary>
        /// 根据指定的 <paramref name="parameters"/>，查找并替换匹配的 <see cref="Sofire.Data.ExecuteParameter"/> 参数值。
        /// </summary>
        /// <param name="parameters">参数集合。</param>
        public void ConvertParameter(XSqlParameterCollection parameters)
        {
            if(string.IsNullOrEmpty(this._Type)) return;
            this.ConvertParameter(parameters[this._Name]);
        }

        /// <summary>
        /// 根据指定的 <paramref name="parameter"/>，查找并替换匹配的 <see cref="Sofire.Data.ExecuteParameter"/> 参数值。
        /// </summary>
        /// <param name="parameter">参数。</param>
        public void ConvertParameter(ExecuteParameter parameter)
        {
            if(string.IsNullOrEmpty(this._Type) || parameter == null) return;

            DbType dbType;
            parameter.Value = ConvertValue(parameter.Value, this._Type, out dbType);
            parameter.Type = dbType;

            //p.Type =
            if(this._Size > 0) parameter.Size = this._Size;
        }

        /// <summary>
        /// 转换指定的值到指定的类型。
        /// </summary>
        /// <param name="value">指定的值。</param>
        /// <param name="type">指定的类型。</param>
        /// <param name="dbType">返回数据库类型</param>
        /// <returns>返回转换后的值。</returns>
        public static object ConvertValue(object value, string type, out DbType dbType)
        {
            if(type == null)
            {
                dbType = DbType.String;
                return value;
            }
            return XSqlBindType.ChangedType(value, type, out dbType);
        }
    }
}
